home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-09-16 | 9.1 KB | 228 lines | [TEXT/CCL2] |
- ;;-*- Mode: Lisp; Package: CCL -*-
- ;; ****************************************************************
- ;; code to implement command-click.
- ;; Command Click copies what you are pointing to where you are typing.
-
- ;; Implementation:
-
- ;; Each type to view which wants to be able to contribute text defines two methods
- ;; (give-text? view) -> t if you can supply text
- ;; (give-text view) -> The text which is to be copied.
-
- ;; Additionally the view-click-event-handler should arrange to call
- ;; (maybe-click-to-copy from-window to-window position continuation)
- ;; where continuation is called if the click wasn't a command click,
- ;; or if it was but there was no text to copy.
-
- ;; Currently the methods for editable-text, dialog-item, sequence-dialog-item, and fred-mixin do this by
- ;; advising the around method for view-click-event-handler.
- ;; Also, the window-select-event-handler is also advised, so that you can command click another to copy from
- ;; another window.
-
- ;; ****************************************************************
-
- ;; Change log
- ;;
- ;; 04/28/93 mwp Release
- ;; 03/19/93 bill missing paren in my translation of MC's fix of 7/29/92
- ;; 07/29/92 mc Fixed menu-of-defs-dialog's give-text to handle null
- ;; window-package (mc = Matt Cornell, cornell@cs.umass.edu)
- ;; -------------- 2.0
- ;; 03/17/92 bill the menu-of-defs-dialog code no longer replaces
- ;; the sequence-dialog-item code.
- ;; -------------- 2.0f3
- ;; 10/04/91 alanr Support the list definitions dialog
- ;; 09/13/91 alice make buffer-insert-carefully undo aware
- ;; 04/18/91 wkf Fix to avoid error when you click where there is no text.
- ;; 01/01/91 bill Prettify, remove LOOP
- ;; 12/11/90 alice fix calls to advise for changed arglist
- ;; 11/05/90 bill Remove reliance on (declaim (ignore ignore))
-
- (in-package :ccl)
-
- (defmethod give-text ((v t)) nil)
- (defmethod give-text? ((v t)) nil)
-
- (defmethod insert-text ((v t) ignore)
- (declare (ignore ignore))
- nil)
- (defmethod insert-text ((v fred-mixin) string)
- (buffer-insert-carefully v string)
- (fred-update v))
-
- (defmethod buffer-insert-carefully ((w fred-mixin) string
- &aux (mark (fred-buffer w)) position append)
- "Insert spaces around insertion, if absent"
- (multiple-value-bind (s e)
- (selection-range w)
- (when (collapse-selection w t)
- (setq append t)
- (ed-delete-with-undo w e s)))
- (setq position (buffer-position mark))
- (unless (or (eql position (buffer-line-start mark position))
- (not (alphanumericp (buffer-char mark (1- position)))))
- (ed-insert-with-undo w " " position append)
- (setq append t)
- (incf position))
- (unless (or (eql position (buffer-line-end mark position))
- (not (alphanumericp (buffer-char mark position))))
- (ed-insert-with-undo w " " position append)
- (setq append t))
- (ed-insert-with-undo w string position append))
-
- (defun maybe-click-to-copy (from to where &optional (continue 'identity))
- (let* ((w (view-window to))
- (insert-into (or (current-key-handler (view-window to)) (and (typep (view-window to) 'fred-window) w))))
- (if insert-into
- (if (and (command-key-p) (not (or (control-key-p) (shift-key-p) (option-key-p))))
- (let ((give-text (deepest-give-text-below-mouse from where)))
- (if (and insert-into give-text)
- (insert-text insert-into give-text)
- (funcall continue)))
- (funcall continue))
- (funcall continue))))
-
- (defmethod current-key-handler ((view t)) nil)
-
- (unless
- (ignore-errors (find-method #'view-click-event-handler '(:around) (mapcar 'find-class '(fred-mixin t))))
- (defmethod view-click-event-handler :around ((view fred-mixin) ignore)
- (declare (ignore ignore))
- (when (next-method-p) (call-next-method))))
-
- (unless
- (ignore-errors (find-method #'view-click-event-handler '(:around) (mapcar 'find-class '(dialog-item t))))
- (defmethod view-click-event-handler :around ((view dialog-item) ignore)
- (declare (ignore ignore))
- (when (next-method-p) (call-next-method))))
-
- (advise window-select-event-handler
- (maybe-click-to-copy (car arglist) (front-window)
- (view-mouse-position (car arglist)) #'(lambda ()(:do-it)))
- :when :around :name maybe-copy)
-
- (advise (:method view-click-event-handler :around (fred-mixin t))
- (destructuring-bind (v where) arglist
- (maybe-click-to-copy v v where #'(lambda() (:do-it))))
- :when :around :name maybe-click-to-copy)
-
- (advise (:method view-click-event-handler :around (dialog-item t))
- (destructuring-bind (v where) arglist
- (maybe-click-to-copy v v (convert-coordinates where (view-container v) v) #'(lambda () (:do-it))))
- :when :around :name maybe-click-to-copy)
-
- (defmethod deepest-give-text-below-mouse ((v simple-view) position &aux w)
- (declare (optimize (speed 3) (safety 0)))
- (setq w (view-window v))
- (setq position (convert-coordinates position v w))
- (rlet ((r :rect))
- (labels ((deepest
- (v^)
- (rset r rect.topleft (convert-coordinates #@(0 0) v^ w))
- (rset r rect.bottomright (convert-coordinates (view-size v^) v^ w))
- (let ((res (and (#_ptinrect position r)
- (let ((lower (do-subviews (s v^)
- (let ((d (deepest s)))
- (when d (return d))))))
- (or lower
- (and (give-text? v^) v^))))))
- res
- )))
- (give-text (deepest w)))))
-
- ;; ****************************************************************
- ;; support for some view types
-
- ;; fred mixins
-
- (defmethod give-text? ((v fred-mixin)) t)
- (defmethod give-text ((v fred-mixin))
- (let ((buffer (fred-buffer v)))
- (multiple-value-bind (start end)
- (buffer-current-sexp-bounds
- buffer
- (fred-point-position v (view-mouse-position v) ))
- (if start
- (buffer-substring buffer start end)
- ""))))
-
- ;; sequence dialog items
- (defmethod give-text? ((v sequence-dialog-item))
- (not (typep (view-container v) 'menu-of-defs-dialog)))
- (defmethod give-text ((v sequence-dialog-item))
- (let ((cell (point-to-cell v (view-mouse-position (view-container v)))))
- (when cell
- (setq * (cell-contents v cell))
- (format nil "~s" (cell-contents v cell)))))
-
- ;; editable-text-dialog-items
- (defmethod give-text? ((v basic-editable-text-dialog-item)) t)
- (defmethod give-text ((v basic-editable-text-dialog-item))
- (let ((buffer (fred-buffer v)))
- (multiple-value-bind
- (start end)
- (buffer-current-sexp-bounds buffer (fred-point-position v (view-mouse-position v) ))
- (buffer-substring buffer start end))))
-
- ;; dialog items return their text
-
- (defmethod give-text? ((v dialog-item)) t)
- (defmethod give-text ((v dialog-item))
- (dialog-item-text v))
-
- ;; get the right line from the inspector
-
- (defmethod clicked-on-selection ((view inspector::inspector-view) where)
- (let ((v (point-v where))
- (line-positions (inspector::line-positions view))
- temp
- new-selection)
- (when line-positions
- (setq temp (aref line-positions 0))
- (dotimes (i (1- (length line-positions)))
- (when (and (<= temp v)
- (< v (setq temp (aref line-positions (1+ i)))))
- (let ((selection (+ (inspector::start-line view) i)))
- (unless (eq (inspector::cached-type-n view selection) :comment)
- (setq new-selection selection)
- (return))))))
- new-selection))
-
- (defmethod give-text ((view inspector::inspector-view))
- (let ((object (inspector::cached-line-n view (clicked-on-selection view (view-mouse-position view)))))
- (setq * object)
- (prin1-to-string object)
- ))
-
- (defmethod view-click-event-handler :around ((v inspector::inspector-view) where)
- (maybe-click-to-copy v v where #'(lambda() (when (next-method-p) (call-next-method)))))
-
- (defmethod give-text? ((v inspector::inspector-view)) t)
-
- ; Support the list definitions dialog
- (defmethod give-text? ((v menu-of-defs-dialog))
- (let ((seq (do-subviews (sv v 'sequence-dialog-item) (return sv))))
- (and seq
- (view-contains-point-p seq (view-mouse-position v)))))
-
- (defmethod give-text ((w menu-of-defs-dialog))
- (let* ((v (do-subviews (sv w 'sequence-dialog-item) (return sv)))
- (cell (point-to-cell v (view-mouse-position w)))
- (package (or (window-package (slot-value w 'my-window)) *package*))
- (contents (let ((*package* package))
- (read-from-string (car (cell-contents v cell))))))
- (when cell
- (let ((function (if (consp contents) (car contents) contents)))
- (when (fboundp function)
- (setq function (symbol-function function))
- (setq * function)
- (if (consp contents)
- (let ((method (ignore-errors
- (nth-value
- 1 (%trace-function-spec-p
- (cons :method contents))))))
- (when method (setq * method)))))))
- (when (consp contents) (setq contents (car contents)))
- (when cell
- (format nil "~a" contents))))
-